package com.nx.vip.factory;

import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.MirroredTypeException;
import java.lang.reflect.Type;

@Getter
public class FactoryAnnotatedClass {
    /**
     * TypeElement代表的是源代码中的类型元素，例如类。然而，TypeElement并不包含类本身的信息。你可以从TypeElement中获取类的名字，
     * 但是你获取不到类的信息，例如它的父类。这种信息需要通过TypeMirror获取。你可以通过调用elements.asType()获取元素的TypeMirror。
     */
    private TypeElement annotatedClassElement; //获取被@Factory注解的原始元素
    private String qualifiedSuperClassName;//获取在 Factory#type()指定的类型合法全名
    private String simpleTypeName; //获取在 Factory#type() 中指定的类型的简单名字
    private String id; //获取在Factory#id()中指定的id

    /**
     * 注意 alcass是一个真正的Class对象
     * @param classElement
     */
    public FactoryAnnotatedClass(TypeElement classElement){
        try {
            //加了@Factory的代码已经编译过了
            this.annotatedClassElement = classElement;
            Factory annotation = classElement.getAnnotation(Factory.class);
            id = annotation.id();   // Read the id value (like "Noodle" or "Egg")
            if (StringUtils.isEmpty(id)) { // 这里我们获取@Factory注解，并且检查id是否为空？如果为空，我们将抛出IllegalArgumentException异常
                throw new IllegalArgumentException(
                        String.format("id() in @%s for class %s is null or empty! that's not allowed",
                                Factory.class.getSimpleName(), classElement.getQualifiedName().toString()));
            }

            Class clazz  = annotation.type();
            qualifiedSuperClassName = clazz.getCanonicalName();
            simpleTypeName = clazz.getSimpleName();
            System.out.println("try123qualifiedSuperClassName="+qualifiedSuperClassName+",simpleTypeName="+simpleTypeName);
        }catch (MirroredTypeException e){
            // 没有编译过，会抛出编译异常，在异常里面，拿到它的注解的id,注解的class,只能通过异常去获取
            DeclaredType classTypeMirror = (DeclaredType) e.getTypeMirror();//MirroredTypeException包含一个TypeMirror，它表示我们未编译类。
            TypeElement classTypeElement = (TypeElement) classTypeMirror.asElement();
            qualifiedSuperClassName = classTypeElement.getQualifiedName().toString();
            simpleTypeName = classTypeElement.getSimpleName().toString();
            System.out.println("exception123qualifiedSuperClassName="+qualifiedSuperClassName+",simpleTypeName="+simpleTypeName);
        }

    }

}
